/*************************************************************************
    > File Name: 003.string_statistics.cpp
    > Author: Maureen 
    > Mail: Maureen@qq.com 
    > Created Time: 三  2/24 20:30:48 2021
 ************************************************************************/
/**
 *
题目描述
蒜头君某天学习了 n 个单词，他想看篇文章来复习下今天学习的内容，现在他想知道每个单词在这篇文章里分别出现了多少次，聪明的你能帮他解决这个问题吗？

输入格式
第一行输入一个整数 n （1 ≤ n ≤ 1000），表示蒜头君学习的 n 个单词。
接下来 n 行，每行输入一个字符串，仅由小写字母组成，长度不超过20。
最后输入一个字符串 S，仅由小写字母组成，长度不超过10^5^，表示蒜头君看的文章。

输出格式
依次输出 n 行，每行输出格式为 i: num,  表示单词的编号（从0开始编号）， num为一个整数，表示第 i 个单词在母串 S 中出现了 num 次。
 */

#include <iostream>
using namespace std;

#define BASE 26
#define MAX_N 20000
struct Node {
    int flag;
    int *cnt; 
    int next[26];
    int fail;
} tree[MAX_N + 5];
int que[MAX_N + 5];
int head, tail;
int *ans[MAX_N + 5];
int root = 1, cnt = 2;
char str[100005];
int n;

int getNewNode() {
    return cnt++;
}

int *insert(const char *str) {
    int p = root;
    for (int i = 0; str[i]; i++) {
        int ind = str[i] - 'a';
        if (tree[p].next[ind] == 0) tree[p].next[ind] = getNewNode();
        p = tree[p].next[ind];
    }
    tree[p].flag = 1;
    if (tree[p].cnt == NULL) {
        tree[p].cnt = (int *)malloc(sizeof(int));
        tree[p].cnt[0] = 0;
    }
    return tree[p].cnt;
}

void build() {
    head = tail = 0;
    tree[root].fail = 0;
    for (int i = 0; i < BASE; i++) {
        if (tree[root].next[i] == 0) {
            tree[root].next[i] = root;
            continue;
        }
        tree[tree[root].next[i]].fail = root;
        que[tail++] = tree[root].next[i];
    }
    while (head < tail) {
        int p = que[head++];
        for (int i = 0; i < BASE; i++) {
            int c = tree[p].next[i];
            int k = tree[p].fail;
            if (c == 0) {
                tree[p].next[i] = tree[k].next[i];
                continue;
            }
            k = tree[k].next[i];
            tree[c].fail = k;
            que[tail++] = c;
        }
    }
    return ;
}

void match(const char *text) {
    int p = root, q;
    for (int i = 0; text[i]; i++) {
        int ind = text[i] - 'a';
        p = tree[p].next[ind];
        q = p;
        while (q) {
            //统计单词出现的次数
            if (tree[q].flag) (*tree[q].cnt) += 1;
            q = tree[q].fail;
        }
    }
    return ;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%s", str);
        ans[i] = insert(str);
    }
    scanf("%s", str);
    build();
    match(str);
    for (int i = 0; i < n; i++) {
        printf("%d: %d\n", i, *ans[i]);
    }
    return 0;
}
